import time
from collections import deque
from vnpy_ctastrategy.template import(
    CtaTemplate
)
from vnpy.trader.object import(
    BarData,
    TickData,
    TradeData,
    OrderData
)

from vnpy_ctastrategy.base import StopOrder
from vnpy.trader.constant import Status

from vnpy.trader.utility import(
    BarData,
    
)

# from vnpy.trader.utility import(
#     BarGenerator,
#     ArrayManager
# )
from typing import Any

class Shock(CtaTemplate):
    """"""

    author="Max"

    direction=1
    go=1
    topPrice=0
    bottomPrice=0

    status=""
    oldPrice=0
    nowPrice=0

    myprice=0
    stopSunPrice=0
    stopYingPrice=0

    volCha=0
    volChaNow=0

    parameters=[  
        "topPrice",
        "bottomPrice",
        "go",
        "direction"
    ]

    variables=[
        "volChaNow",
        "myprice",
        "stopSunPrice",
        "stopYingPrice"
        
    ]

    def __init__(self, cta_engine: Any, strategy_name: str, vt_symbol: str, setting: dict) -> None:
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)
        
        # self.huanjing="实盘"
        self.huanjing="实盘"

        self.ticks=deque([TickData],maxlen=20)

        self.topPrice=0
        self.bottomPrice=0

        self.bidPrice=0
        self.askPrice=0
        self.volume=0
        self.lastPrice=0
        self.lastAskPrice=0
        self.lastBidPrice=0
        self.lastVolume=0

        self.orderid=""
        self.orderStatus=""
        self.stoporderid=""
        self.stoporderStatus=""
        self.vt_stoporderid=""
        self.vt_stoporderStatus=""
        self.limitorderid=""
        self.limitorderStatus=""
        self.status="等待中"
        self.lastStatus=""
        # self.msg=f",pos={self.pos},orderid={self.orderid},myprice={self.myprice}，stopSunPrice={self.stopSunPrice},stopYingPrice={self.stopYingPrice},volCha={self.volChaNow}"
        # self.bg = BarGenerator(self.on_bar)
        # self.am = ArrayManager()

    def on_init(self) -> None:
        self.write_log("市价LiangCha7 策略初始化")
        # self.load_bar(10)

    def on_start(self) -> None:
        self.pos=0
        self.lastStatus=""
        self.write_log("市价LiangCha 策略启动")
    
    def on_stop(self) -> None:
        # self.startTrade=0
        self.write_log("市价LiangCha 策略停止")

    def on_trade(self, trade: TradeData) -> None:
        self.myLog(f"on_order {trade.direction.value}{trade.offset.value},{trade.price},{trade.orderid}")
        self.myLog(f"********已成交******** {trade.direction.value}{trade.offset.value},{trade.price} ")
        return super().on_trade(trade)

    def on_stop_order(self, stop_order: StopOrder) -> None:
        return super().on_stop_order(stop_order)

    def on_order(self, order: OrderData) -> None:
        self.myLog(f"on_order {order.direction.value}{order.offset.value},{order.price},{order.status.value},{order.orderid}")
        if self.orderid.find(order.orderid)!=-1:
            self.orderStatus=order.status.value
            if order.status.value==Status.REJECTED.value:
                self.myLog("........已拒单........")
                self.status="等待中"
            elif order.status.value==Status.CANCELLED.value:
                self.myLog("........已撤单........")
                # self.direction=self.direction*-1
                self.status="等待中"
            elif order.status.value==Status.ALLTRADED.value:
                self.myLog(f"........已开仓,开止盈........")
                self.status="开止盈"
                if self.direction==1:
                    self.limitorderid=self.sell(self.stopYingPrice, 1)[0]
                else:
                    self.limitorderid=self.cover(self.stopYingPrice, 1)[0]
                # TODO 止盈单挂单失败 需要特殊处理
        elif self.limitorderid.find(order.orderid)!=-1:
            self.limitorderStatus=order.status.value
            if order.status.value==Status.NOTTRADED.value:
                self.myLog("........已开盈........")
                self.status="波动中"
            elif order.status.value==Status.ALLTRADED.value:
                self.myLog("........已止盈,等待中........")
                # self.go=0
                # self.direction=self.direction*-1
                self.status="等待中"
            elif order.status.value==Status.CANCELLED.value:
                self.myLog(f"........已撤盈,开止损........")
                self.status="开止损"
                if self.direction==1:
                    self.stoporderid=self.sell(self.stopSunPrice, 1)[0]
                else:
                    self.stoporderid=self.cover(self.stopSunPrice, 1)[0]
        elif self.stoporderid.find(order.orderid)!=-1:
            self.stoporderStatus=order.status.value
            if order.status.value==Status.ALLTRADED.value:
                self.myLog("........已止损,等待中........")
                # self.direction=0
                # self.go=0
                self.status="等待中"
            elif order.status.value==Status.NOTTRADED.value or order.status.value==Status.SUBMITTING.value:
                self.myLog("........止损中........")
        return super().on_order(order)

    def on_tick(self, tick: TickData) -> None:

        # 每一个tick发生了什么
        self.volume=tick.volume-self.lastVolume
        
        if self.volume!=0:
            print(f"原=={self.lastAskPrice}/{self.lastBidPrice},现={tick.ask_price_1}/{tick.bid_price_1},最新={tick.last_price},V={self.volume}")
            if self.lastBidPrice==tick.bid_price_1 and self.lastAskPrice==tick.ask_price_1:
                if tick.last_price==tick.ask_price_1:
                    print(f"B 小买单对价,V={self.volume}")
                elif tick.last_price==tick.bid_price_1:
                    print(f"A 小卖单对价,V={self.volume}")
                else:
                    print("其他 2")
            elif tick.bid_price_1==self.lastAskPrice and tick.last_price==self.lastAskPrice:
                print(f"B ******大买单对价,吃完变买1 ,V={self.volume}")
            elif tick.ask_price_1==self.lastBidPrice and tick.last_price==self.lastBidPrice:
                print(f"A ******大卖单对价,吃完变卖1 ,V={self.volume}")
            elif tick.bid_price_1==self.lastBidPrice and tick.ask_price_1>self.lastAskPrice:
                if tick.last_price==self.lastAskPrice:
                    print(f"B ******大买单跳价Step 1,吃完卖1 ,V={self.volume}")
                elif tick.last_price>self.lastAskPrice:
                    print(f"B ******大买单跳价Step 2,吃到卖2 ,V={self.volume}")
                else:
                    print("其他 3")
            elif tick.ask_price_1==self.lastAskPrice and tick.bid_price_1<self.bidPrice:
                if tick.last_price==self.lastBidPrice:
                    print(f"A ******大卖单跳价Step 1,吃完买单1 ,V={self.volume}")
                elif tick.last_price>self.lastBidPrice:
                    print(f"A ******大卖单跳价Step 2,吃到买单2 ,V={self.volume}")
                else:
                    print("其他 4")
            else:
                print("其他 1")
        # tick.last_volume=tick.volume-self.lastVolume

        # print("-------------")tick.
        # print(f"tick.exchange={tick.exchange.DCE}")
        # print(f"tick.extra={tick.extra}")
        # print(f"tick.last_volume={tick.last_volume}")
        # print(f"tick.symbol={tick.symbol}")
        # print(f"tick.turnover={tick.turnover}")
        # print(f"tick.pre_close={tick.pre_close}")
        # print(f"tick.volume={tick.volume}")

        # 存放tick
        # if self.ticks.__len__)>20:
        #     self.ticks.popleft()
        # self.ticks.append(tick)  
        # 获取Aprice up值
        # openPrice=0
        # up=self.getPriceUp(self.ticks,tick.ask_price_1,)
        # print(f"up%={up}%,lastAskPrice[{self.lastAskPrice}] -> askPrice[{tick.ask_price_1}]")
        # if up>80:
        #     openPrice=0

        # LiangCha.myLog(self,f"on tick={tick.last_price}")
        # self.tick=tick
        # self.nowPrice=tick.last_price
        # self.oldPrice=tick.last_price
        self.bidPrice=tick.bid_price_1
        self.askPrice=tick.ask_price_1
        
        # self.volChaNow=tick.bid_volume_1-tick.ask_volume_1
        if self.trading:
            if self.status=="等待中":
                self.myLog(f"等待中,监控参数={self.direction}")
                # self.lastStatus="等待中"
                if self.orderid:
                    self.orderid=""
                    self.orderStatus="等待中"
                    self.stoporderid=""
                    self.stoporderStatus="等待中"
                    self.vt_stoporderid=""
                    self.vt_stoporderStatus="等待中"
                    self.limitorderid=""
                    self.limitorderStatus="等待中"
                # if self.volChaNow<=self.volCha:
                # 计算开仓条件
                self.go=0
                if self.direction!=0 and self.go:
                    if (tick.ask_price_1==self.topPrice and tick.bid_price_1<self.topPrice) \
                        or (tick.bid_price_1==self.bottomPrice and tick.ask_price_1>self.bottomPrice):
                        if tick.ask_price_1==self.topPrice:
                            self.direction=-1
                        else:
                            self.direction=1

                    # 做空 tick.ask_price_1==self.topPrice
                    # if tick.ask_price_1==self.topPrice:
                    #     self.direction=-1

                        self.status="开仓中"
                        # self.myLog("========开仓中========",tick=tick)
                        if self.huanjing=="测试":
                            if self.direction==1:
                                self.myprice=tick.ask_price_1
                                self.orderid=self.buy(self.myprice, 1)[0]
                                self.stopSunPrice=self.myprice-2
                                self.stopYingPrice=self.myprice+1
                            else:
                                self.myprice=tick.bid_price_1
                                self.orderid=self.short(self.myprice, 1)[0]
                                self.stopSunPrice=self.myprice+2
                                self.stopYingPrice=self.myprice-1
                        else:
                            ying=3
                            sun=2
                            if self.direction==1:
                                self.myprice=tick.bid_price_1
                                self.orderid=self.buy(self.myprice, 1)[0]
                                self.stopSunPrice=self.myprice-sun
                                self.stopYingPrice=self.myprice+ying
                            else:
                                self.myprice=tick.ask_price_1
                                self.orderid=self.short(self.myprice, 1)[0]
                                self.stopSunPrice=self.myprice+sun
                                self.stopYingPrice=self.myprice-ying
                        self.myLog(f"========开仓中========")
                else:
                    if self.lastStatus!="暂停中":
                        self.myLog("........暂停中........")
                        self.lastStatus="暂停中"
            elif self.status=="开仓中":
                # if self.myprice!=tick.ask_price_1:
                if self.huanjing=="测试":
                    if (self.direction==1 and self.myprice!=tick.ask_price_1) \
                        or (self.direction==-1 and self.myprice!=tick.bid_price_1) :
                        self.status="撤单中"
                        # self.myLog("撤单中",tick=tick)
                        self.myLog(f"........撤单中........")
                        self.cancel_order(self.orderid)
                        # TODO 极端情况 发送撤单的时候 已经成交 需要特殊处理
                    else:
                        if self.lastPrice!=tick.last_price:
                            self.myLog("........待开仓........")
                else:
                    if (self.direction==1 and self.myprice!=tick.bid_price_1) \
                        or (self.direction==-1 and self.myprice!=tick.ask_price_1) :
                        self.status="撤单中"
                        # self.myLog("撤单中",tick=tick)
                        self.myLog("........撤单中........")
                        self.cancel_order(self.orderid)
                        # TODO 极端情况 发送撤单的时候 已经成交 需要特殊处理
                    else:
                        self.myLog("........待开仓........")
            # elif self.status=="撤单中":
            #     self.myLog("撤单中") 
            elif self.status=="波动中":
                if (self.direction==1 and tick.bid_price_1<=self.stopSunPrice) \
                    or (self.direction==-1 and tick.ask_price_1>=self.stopSunPrice):
                    # self.myLog("已触损,撤止盈",tick=tick)
                    # self.myLog("........已触损,撤止盈........")
                    up,total=self.getPriceUp(self.ticks,tick.ask_price_1)
                    self.myLog("........已触损........")
                    # self.myLog(f"M={self.myprice},S={self.stopSunPrice},up%={up},down%={down},countTotal={countTotal}")
                    if total>6:
                        if self.direction==1 and up>=75:
                            self.cancel_order(self.limitorderid)
                        elif self.direction==-1 and up <= 25:
                            self.cancel_order(self.limitorderid)
                else:
                    if self.lastPrice!=tick.last_price:
                        self.myLog(f"........波动中........")
            # elif self.status=="开止盈":
            #     self.status="pending"
            #     if self.direction==1:
            #         if self.bidPrice<self.myprice:
            #             # 滑点开仓 止损多1
            #             self.stopSunPrice=self.stopSunPrice-1
            #             self.myLog(f"........滑点买开止损多1........")
            #         self.limitorderid=self.sell(self.stopYingPrice, 1)[0]
            #     else:
            #         if self.askPrice>self.myprice:
            #             # 滑点开仓 止损多1
            #             self.stopSunPrice=self.stopSunPrice+1
            #             self.myLog(f"........滑点卖开止损多1........")
            #         self.limitorderid=self.cover(self.stopYingPrice, 1)[0]
            #     # TODO 止盈单挂单失败 需要特殊处理
            else:
                # self.myLog(self.status,tick=tick)
                self.myLog("........pending........")
        self.lastPrice=tick.last_price
        self.lastAskPrice=tick.ask_price_1
        self.lastBidPrice=tick.bid_price_1
        self.lastVolume=tick.volume

    def myLog(self,msg="",onlyTime=False) ->None:
        t=time.strftime('%H:%M:%S',time.localtime(time.time()))
        s=f"最新={self.lastPrice} 开价={self.myprice} 方向={self.direction} 买一={self.bidPrice} 卖一={self.askPrice} 止损={self.stopSunPrice} 止盈={self.stopYingPrice} id={self.orderid}"
        if msg:
            print(f"{t} {msg} {s}")
        else:
            print(f"{t} {s}")

    def getPriceUp(self,ticks:deque[TickData],price:float,up:bool=True)->int:
        countUp=0
        countDown=0
        countTotal=0
        for t in ticks:
            if t.ask_price_1==price:
                countTotal+=1
                if t.last_price==price:
                    countUp+=1
                else:
                    countDown+=1
        up=int(countUp/countTotal*100)
        down=int(countDown/countTotal*100)
        # print(f"up%={up},down%={down},countTotal={countTotal}")
        return int(countUp/countTotal*100),countTotal

